#ifdef DEBUG
  #include <iostream>
  #include <cassert>
  #define dout(x) std::cout << x
#else
  #define dout(x)
  #define assert(x)
#endif

#include <cstdio>
#include <vector>
#include <queue>
#include <map>

struct edge {
  int next;
  int dst;
  edge(int _next = 0, int _dst = 0): next(_next), dst(_dst) { }
};

struct node {
  int id;
  int dst;
  node(int _id = 0, int _dst = 0): id(_id), dst(_dst) { }
  bool operator < (const node& n2) const {
    return dst == n2.dst ? id < n2.id : dst > n2.dst;
  }
};

using namespace std;

const int maxn = 10001;
const int big = 1000000000;

int v, k, start, end;
vector<edge> adj[maxn];
bool visited[maxn];
int dst[maxn];

void dijkstra();

int main() {
  int numcases = 0;
  scanf("%d", &numcases);
  for (int ii = 0; ii < numcases; ++ii) {
    scanf("%d %d", &v, &k);
    for (int jj = 1; jj <= v; ++jj) {
      visited[jj] = false;
      dst[jj] = big;
      adj[jj].clear();
    }
    for (int jj = 0; jj < k; ++jj) {
      int from, to, cost;
      scanf("%d %d %d", &from, &to, &cost);
      adj[from].push_back(edge(to, cost));
    }
    scanf("%d %d", &start, &end);
    dijkstra();
    if (!visited[end]) {
      printf("NO\n");
    } else {
      printf("%d\n", dst[end]);
    }
  }
  return 0;
}

void dijkstra() {
  priority_queue<node> q;
  dst[start] = 0;
  q.push(node(start, 0));
  while (!q.empty()) {
    int cur = q.top().id;
    q.pop();
    if (visited[cur]) {
      continue;
    }
    visited[cur] = true;
    if (cur == end) {
      return;
    }
    for (unsigned int ii = 0; ii < adj[cur].size(); ++ii) {
      const edge& e = adj[cur][ii];
      if (dst[e.next] > dst[cur] + e.dst) {
        dst[e.next] = dst[cur] + e.dst;
        q.push(node(e.next, dst[e.next]));
      }
    }
  }
}
